﻿using System;

namespace KryptecizerBase.Encryption
{
    /// <summary>
    /// Encryptor for TextBasedKryptOjects.
    /// Encrypts with Vigenère-encryption-algorithm.
    /// </summary>
    public class VigenereEncryptor : KryptoTextEncryptor
    {
        /// <summary>
        /// Password for encryption
        /// </summary>
        private string _pw;

        /// <summary>
        /// Initializes a new instance of the <see cref="VigenereEncryptor"/> class.
        /// </summary>
        /// <param name="pw">The password.</param>
        public VigenereEncryptor(string pw)
            : base()
        {
            _pw = pw.ToUpper();
        }

        /// <summary>
        /// Implementation of abstract method to encrypt the specified krypto text.
        /// Calls OnEncryptionProcessing method.
        /// </summary>
        /// <param name="kryptoText">The krypto text.</param>
        /// <returns>success</returns>
        protected override bool Encrypt(KryptoText kryptoText)
        {
            _KryptoText.Fill(String.Empty);
            string text = kryptoText.GetAsString().Replace(" ", String.Empty);
            KryptoText ktext = new KryptoText();

            text = KryptoText.EleminateSpecialSigns(text);
            ktext.Fill(text);
            int pwIndex = 0;
            int offset;
            try
            {
                double onePercent = ktext.Count / 100d;
                for (int i = 0; i < ktext.Count; i++)
                {
                    offset = ((int)_pw[pwIndex]) - 64;
                    offset -= 1;
                    _KryptoText.Add(ktext.Shift(i, offset));
                    OnEncryptionProcessing((int)((double)i / onePercent));
                    pwIndex++;
                    if(pwIndex >= _pw.Length)
                        pwIndex = 0;
                }
                text = _KryptoText.GetAsString();
                text = KryptoText.GetGroupedString(text);
                _KryptoText.Clear();
                foreach (Char item in text)
                    _KryptoText.Add(item);
                OnEncryptionProcessing(100);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}
